package com.wan37.client.service;

import com.wan37.client.handler.ClientHandler;
import com.wan37.client.service.cache.RoleServiceCache;
import com.wan37.client.service.cache.UserServiceCache;
import com.wan37.protobuf.constant.AllRoleLabel;
import com.wan37.protobuf.constant.SkillLabel;
import com.wan37.protobuf.message.client2server.game.GameEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author : luoyong
 * @date : 2020-07-02 09:35
 **/
@Component("pVPFightingService")
public class PVPFightingService implements FightingService {
    private ClientHandler clientHandler = ClientHandler.getInstance();
    private final static Logger logger = LoggerFactory.getLogger(PVPFightingService.class);

    @Autowired
    private UserServiceCache userServiceCache;
    @Autowired
    private RoleServiceCache roleServiceCache;
    /**
     * boss场景战斗线程池，方便停止战斗
     */
    public final static Map<String, ThreadPoolExecutor> sceneNameToExecutor = new ConcurrentHashMap<>();

    volatile List<String> roleIdList = new CopyOnWriteArrayList<>();
    volatile List<String> roleIdList1 = new CopyOnWriteArrayList<>();
    @Override
    public void fighting() {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), r -> {
            Thread thread = new Thread(r);
            thread.setName("玩家和boss对战技能线程池");
            thread.setDaemon(true);
            return thread;
        });
        sceneNameToExecutor.put(clientHandler.current_scene, threadPool);
        roleIdList.clear();
        roleIdList1.clear();
        for (Map.Entry<String, UserServiceCache.UserIn> entry : userServiceCache.getUserInMap().entrySet()){
            if (entry.getKey().equals(clientHandler.selfId)){
                for (String roleId : entry.getValue().getRoleIdList()) {
                    roleIdList.add(roleId);
                    for (GameEntity.Skill skill : roleServiceCache.getRoleInMap().get(roleId).getSkillMap().values()) {
                        DelayThreadPool.initAdd(roleId, skill);
                    }
                }
            }else {
                for (String roleId : entry.getValue().getRoleIdList()) {
                    roleIdList1.add(roleId);
                    for (GameEntity.Skill skill : roleServiceCache.getRoleInMap().get(roleId).getSkillMap().values()) {
                        DelayThreadPool.initAdd(roleId, skill);
                    }
                }
            }
        }
        for (String roleId : roleIdList) {
            playerSelectAttackObject(roleServiceCache.getRoleInMap().get(roleId).getRole());
        }
    }

    public void playerSelectAttackObject(GameEntity.Role role) {
        //判断是否是自身的对象，只会触发自己的对象进行自动攻击
        if (!role.getUserId().equals(clientHandler.selfId)){
            return;
        }
        if (role.getAllRole().getStatus() == AllRoleLabel.STATUS_DIE){
            logger.info("{}角色已经死亡",role.getAllRole().getNickname());
            return;
        }
        /**
         * 判断优先攻击集合里面是否有值,没有就随便取一个存活攻击
         */
        if (role.getAllRole().getAttackEntityIdList() != null && !role.getAllRole().getAttackEntityIdList().isEmpty()) {
            for (GameEntity.stringMsg stringMsg : role.getAllRole().getAttackEntityIdList()) {
                GameEntity.Role role1 = roleServiceCache.getRoleInMap().get(stringMsg.getStringId()).getRole();
                if ( role1.getAllRole().getStatus() == AllRoleLabel.STATUS_LIFE) {
                    playerAttackPlayer(role, role1);
                    break;
                }
            }
        }else {
            for (String roleId : roleIdList1) {
                GameEntity.Role role1 = roleServiceCache.getRoleInMap().get(roleId).getRole();
                if (role1.getAllRole().getStatus() == AllRoleLabel.STATUS_LIFE) {
                    playerAttackPlayer(role, role1);
                    break;
                }
            }
        }
    }

    public void playerAttackPlayer(GameEntity.Role role, GameEntity.Role role2) {
        sceneNameToExecutor.get(clientHandler.current_scene).execute(() -> {
            if (role.getAllRole().getStatus() == AllRoleLabel.STATUS_DIE) {
                logger.info("角色{} 已经死亡不能攻击！", role.getAllRole().getNickname());
                return;
            }
            if (role2.getAllRole().getStatus() == AllRoleLabel.STATUS_DIE) {
                logger.info("角色{} 已经死亡不能被攻击！", role2.getAllRole().getNickname());
                return;
            }
            //从优先级别队列中取一个技能
            GameEntity.Skill skill = SkillService.getPbqSkill(role.getAllRole().getAllRoleId());
            if (skill != null) {
                if (role.getAllRole().getHP() - skill.getCostHP() < 0) {
                    logger.info(role.getAllRole().getNickname() + " 使用 " +
                            skill.getName() + " 技能失败，HP不够 ");
                    DelayThreadPool.add(role.getAllRole().getAllRoleId(), skill, 2);
                } else {
                    if (skill.getLabel().startsWith(SkillLabel.ENEMY, 1)) {
                        //释放技能
                        clientHandler.sendAttackMessage(role.getAllRole().getAllRoleId(), role2.getAllRole().getAllRoleId(), skill.getId());
                        logger.info(role.getAllRole().getNickname() + " 使用 " +
                                skill.getName() + " 技能攻击了 " + role2.getAllRole().getNickname());
                    } else {
                        //释放技能
                        clientHandler.sendAttackMessage(role.getAllRole().getAllRoleId(), role.getAllRole().getAllRoleId(), skill.getId());
                        logger.info(role.getAllRole().getNickname() + " 使用 " +
                                skill.getName() + " 技能提升了 " + role.getAllRole().getNickname());
                    }
                }
            }
        });
    }
}
